library(dplyr)
library(ggplot2)
library(TSstudio)
library(tsibble)
library(plotly)
library(ggpubr)
library(gtools)
library(lubridate)
library(rstatix)
library("readxl")
library(data.table)
## import
Copy_of_Residential_Profiles <- read_excel("~/Documents/NREL Interview Materials/NREL Research/Datasets/Copy of Residential-Profiles.xlsx")
View(Copy_of_Residential_Profiles)
Copy_of_PEV_Profiles <- read_excel("~/Documents/NREL Interview Materials/NREL Research/Datasets/Copy of PEV-Profiles-L1.xlsx")
View(Copy_of_Residential_Profiles)
## master data set for residential electricity demand
ResUse <- Copy_of_Residential_Profiles %>% group_by(Time, Time = as.POSIXct(Time, format = "%Y-%m-%dT%H:%M"))
## master data set for EV charging electricity usage
EVuse <- Copy_of_PEV_Profiles %>% group_by(Time, Time = as.POSIXct(Time, format = "%Y-%m-%dT%H:%M"))
## data sets with average watt demand/usage for every 10 minutes measured
AvgResUse <- data.frame(Time = ResUse$Time,
Watts = rowMeans(ResUse[c(-1)]))
AvgEvUse <- data.frame(Time = EVuse$Time,
Watts = rowMeans(EVuse[c(-1)]))
## temperature data set being used later on in analysis
Temp <- read_excel("~/Documents/NREL Interview Materials/NREL Research/Datasets/Kansas City Average Daily Weather 2010.xlsx")
## other various data sets
CombinedWatts <- data.frame(Time = AvgEvUse$Time, ResWatts = AvgResUse$Watts, EvWatts = AvgEvUse$Watts)
WattTS <- ts(data = CombinedWatts[c("ResWatts", "EvWatts")],
frequency = 365,
start = c(2010, 1),
end = c(2011, 1))
## combined data set with daily temperature data, setting EV and residential data to daily averages
newdate <- format(CombinedWatts$Time, format="%Y:%m:%d")
df <- data.frame(newdate, CombinedWatts$ResWatts, CombinedWatts$EvWatts)
Watt_lm <- setDT(df)[, lapply(.SD, mean, na.rm=TRUE), by=newdate]
Watt_lm <- cbind(Watt_lm, Temp[c(-1)])
Watt_lm <- rename(Watt_lm, ResWatts = "CombinedWatts.ResWatts", EvWatts = "CombinedWatts.EvWatts", Day = newdate)
Watt_lm$Day <- ymd(Watt_lm$Day)
# initial plot showing average residential electricity demand
AvgResPlot <- ggplot(AvgResUse, aes(Time, Watts))
AvgResPlot + geom_line() + geom_smooth(method = NULL, se = 99)

# initial plot showing average EV charging without geom_line() - not useful here
AvgEvPlot <- ggplot(AvgEvUse, aes(Time, Watts))
AvgEvPlot + geom_smooth(method = NULL, se = 99, color = "red")

AvgResPlot + geom_line() +
geom_smooth(method = NULL, se = 99, aes(color = "Residential")) +
geom_smooth(data = AvgEvUse, method = NULL, se = 99, aes(color = "Electric Vehicle")) +
ggtitle("Average Electricity Demand in Watts") + xlab("Time") +
ylab("Watt Hours") +
labs(subtitle = "Measured Every 10 Minutes (99% CI)") +
scale_colour_manual(name="legend", values=c("red", "blue"))

ts_plot(WattTS,
title = "Residential Electricity Demand vs Residential EV Electricity Use",
Ytitle = "Watts",
Xtitle = "Time (2010)",
slider = TRUE)
WattTSnew <- as_tsibble(CombinedWatts, index = Time)
plot(running(WattTSnew$ResWatts, WattTSnew$EvWatts, fun = cor, width=3500), pch = '.', main="Running Correlation of EV Charging vs Residential Electricity Demand",
xlab="Running Observations",
ylab="Correlation",
sub="1 month ≈ 4,333 Observations")

DailyWattPlot <- ggplot(Watt_lm, aes(Day, ResWatts))
DailyWattPlot + geom_line() +
geom_smooth(method = NULL, se = 99, aes(color = "Residential")) +
geom_smooth(data = Watt_lm, method = NULL, se = 99, aes(x = Day, y = EvWatts, color = "Electric Vehicle")) +
ggtitle("Average Electricity Demand in Watts") + xlab("Time") +
ylab("Watt Hours") +
labs(subtitle = "Daily Average (99% CI)") +
scale_colour_manual(name="legend", values=c("red", "blue"))

## this code is added so two graphs can be compared side-by-side
AvgResPlot + geom_line() +
geom_smooth(method = NULL, se = 99, aes(color = "Residential")) +
geom_smooth(data = AvgEvUse, method = NULL, se = 99, aes(color = "Electric Vehicle")) +
ggtitle("Average Electricity Demand in Watts") + xlab("Time") +
ylab("Watt Hours") +
labs(subtitle = "Measured Every 10 Minutes (99% CI)") +
scale_colour_manual(name="legend", values=c("red", "blue"))

## daily average
plot(Watt_lm$ResWatts, Watt_lm$EvWatts, main = "Correlation of Daily Average Electricity (Watt) Usage",
xlab = "Residential Electricity Usage", ylab = "EV Charging Usage",
pch = 1, frame = FALSE)
abline(lm(Watt_lm$EvWatts ~ Watt_lm$ResWatts, data = Watt_lm), col = "blue")

## measured every 10 minutes
plot(CombinedWatts$ResWatts, CombinedWatts$EvWatts, main = "Correlation of Average Electricity (Watt) Usage, Measured Every 10 Minutes",
xlab = "Residential Electricity Usage", ylab = "EV Charging Usage",
pch = 1, frame = FALSE)
abline(lm(CombinedWatts$EvWatts ~ CombinedWatts$ResWatts, data = CombinedWatts), col = "blue")

## scatterplot matrix
pairs(~ ResWatts + EvWatts + Temp, data = Watt_lm)

##Shows all paired p-values
cor_p <- cor_pmat(Watt_lm[, -1])
cor_p
##Shows all correlations
cor_test <- cor_mat(Watt_lm[, -1])
cor_test
NA
## Daily average full model with ResUse response variable
Model1 <- lm(ResWatts ~ EvWatts + Temp, data = Watt_lm)
summary(Model1)
## Daily average full model with EvUse response variable
Model2 <- lm(EvWatts ~ ResWatts + Temp, data = Watt_lm)
summary(Model2)
## Daily averages and Temperature
Model3 <- lm(ResWatts ~ Temp, data = Watt_lm)
summary(Model3)
Model4 <- lm(ResWatts ~ EvWatts, data = Watt_lm)
summary(Model4)
Model5 <- lm(EvWatts ~ Temp, data = Watt_lm)
summary(Model5)
## Every 10 minutes with Residential Use as response variable. Shows much stronger correlation
Model6 <- lm(ResWatts ~ EvWatts, data = CombinedWatts)
summary(Model6)
LS0tCnRpdGxlOiBRdWFudGl0YXRpdmUgQW5hbHlzaXMgLSBFbGVjdHJpYyBWZWhpY2xlIEltcGFjdHMgb24gUmVzaWRlbnRpYWwgRWxlY3RyaWNpdHkKICBEZW1hbmQKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgZmlnX3dpZHRoOiAxMAogICAgZmlnX2hlaWdodDogOAogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQoKYGBge3IgaW1wb3J0IGxpYnJhcmllc30KbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KFRTc3R1ZGlvKQpsaWJyYXJ5KHRzaWJibGUpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShndG9vbHMpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KHJzdGF0aXgpCmxpYnJhcnkoInJlYWR4bCIpCmxpYnJhcnkoZGF0YS50YWJsZSkKCmBgYAoKYGBge3IgcmVuYW1lL3RyYW5zZm9ybSBkYXRhc2V0c30KIyMgaW1wb3J0IAoKQ29weV9vZl9SZXNpZGVudGlhbF9Qcm9maWxlcyA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9OUkVMIEludGVydmlldyBNYXRlcmlhbHMvTlJFTCBSZXNlYXJjaC9EYXRhc2V0cy9Db3B5IG9mIFJlc2lkZW50aWFsLVByb2ZpbGVzLnhsc3giKQpWaWV3KENvcHlfb2ZfUmVzaWRlbnRpYWxfUHJvZmlsZXMpCgpDb3B5X29mX1BFVl9Qcm9maWxlcyA8LSByZWFkX2V4Y2VsKCJ+L0RvY3VtZW50cy9OUkVMIEludGVydmlldyBNYXRlcmlhbHMvTlJFTCBSZXNlYXJjaC9EYXRhc2V0cy9Db3B5IG9mIFBFVi1Qcm9maWxlcy1MMS54bHN4IikKVmlldyhDb3B5X29mX1Jlc2lkZW50aWFsX1Byb2ZpbGVzKQoKCiMjIG1hc3RlciBkYXRhIHNldCBmb3IgcmVzaWRlbnRpYWwgZWxlY3RyaWNpdHkgZGVtYW5kClJlc1VzZSA8LSBDb3B5X29mX1Jlc2lkZW50aWFsX1Byb2ZpbGVzICU+JSBncm91cF9ieShUaW1lLCBUaW1lID0gYXMuUE9TSVhjdChUaW1lLCBmb3JtYXQgPSAiJVktJW0tJWRUJUg6JU0iKSkKCiMjIG1hc3RlciBkYXRhIHNldCBmb3IgRVYgY2hhcmdpbmcgZWxlY3RyaWNpdHkgdXNhZ2UKRVZ1c2UgPC0gQ29weV9vZl9QRVZfUHJvZmlsZXMgJT4lIGdyb3VwX2J5KFRpbWUsIFRpbWUgPSBhcy5QT1NJWGN0KFRpbWUsIGZvcm1hdCA9ICIlWS0lbS0lZFQlSDolTSIpKQoKIyMgZGF0YSBzZXRzIHdpdGggYXZlcmFnZSB3YXR0IGRlbWFuZC91c2FnZSBmb3IgZXZlcnkgMTAgbWludXRlcyBtZWFzdXJlZApBdmdSZXNVc2UgPC0gZGF0YS5mcmFtZShUaW1lID0gUmVzVXNlJFRpbWUsIAogICAgICAgICAgICAgICAgICAgICAgICBXYXR0cyA9IHJvd01lYW5zKFJlc1VzZVtjKC0xKV0pKQoKQXZnRXZVc2UgPC0gZGF0YS5mcmFtZShUaW1lID0gRVZ1c2UkVGltZSwgCiAgICAgICAgICAgICAgICAgICAgICAgV2F0dHMgPSByb3dNZWFucyhFVnVzZVtjKC0xKV0pKQoKIyMgdGVtcGVyYXR1cmUgZGF0YSBzZXQgYmVpbmcgdXNlZCBsYXRlciBvbiBpbiBhbmFseXNpcwpUZW1wIDwtIHJlYWRfZXhjZWwoIn4vRG9jdW1lbnRzL05SRUwgSW50ZXJ2aWV3IE1hdGVyaWFscy9OUkVMIFJlc2VhcmNoL0RhdGFzZXRzL0thbnNhcyBDaXR5IEF2ZXJhZ2UgRGFpbHkgV2VhdGhlciAyMDEwLnhsc3giKQoKIyMgb3RoZXIgdmFyaW91cyBkYXRhIHNldHMKCkNvbWJpbmVkV2F0dHMgPC0gZGF0YS5mcmFtZShUaW1lID0gQXZnRXZVc2UkVGltZSwgUmVzV2F0dHMgPSBBdmdSZXNVc2UkV2F0dHMsIEV2V2F0dHMgPSBBdmdFdlVzZSRXYXR0cykKCldhdHRUUyA8LSB0cyhkYXRhID0gQ29tYmluZWRXYXR0c1tjKCJSZXNXYXR0cyIsICJFdldhdHRzIildLAogICBmcmVxdWVuY3kgPSAzNjUsCiAgIHN0YXJ0ID0gYygyMDEwLCAxKSwKICAgZW5kID0gYygyMDExLCAxKSkKCgojIyBjb21iaW5lZCBkYXRhIHNldCB3aXRoIGRhaWx5IHRlbXBlcmF0dXJlIGRhdGEsIHNldHRpbmcgRVYgYW5kIHJlc2lkZW50aWFsIGRhdGEgdG8gZGFpbHkgYXZlcmFnZXMKCm5ld2RhdGUgPC0gZm9ybWF0KENvbWJpbmVkV2F0dHMkVGltZSwgZm9ybWF0PSIlWTolbTolZCIpCgpkZiA8LSBkYXRhLmZyYW1lKG5ld2RhdGUsIENvbWJpbmVkV2F0dHMkUmVzV2F0dHMsIENvbWJpbmVkV2F0dHMkRXZXYXR0cykgCgpXYXR0X2xtIDwtIHNldERUKGRmKVssIGxhcHBseSguU0QsIG1lYW4sIG5hLnJtPVRSVUUpLCBieT1uZXdkYXRlXQoKV2F0dF9sbSA8LSBjYmluZChXYXR0X2xtLCBUZW1wW2MoLTEpXSkKCldhdHRfbG0gPC0gcmVuYW1lKFdhdHRfbG0sIFJlc1dhdHRzID0gIkNvbWJpbmVkV2F0dHMuUmVzV2F0dHMiLCBFdldhdHRzID0gIkNvbWJpbmVkV2F0dHMuRXZXYXR0cyIsIERheSA9IG5ld2RhdGUpCgpXYXR0X2xtJERheSA8LSB5bWQoV2F0dF9sbSREYXkpCgpgYGAKCmBgYHtyIHZpZXcgZGF0YXNldHMvcmVsYXRpb25zaGlwc30KCiMgaW5pdGlhbCBwbG90IHNob3dpbmcgYXZlcmFnZSByZXNpZGVudGlhbCBlbGVjdHJpY2l0eSBkZW1hbmQKQXZnUmVzUGxvdCA8LSBnZ3Bsb3QoQXZnUmVzVXNlLCBhZXMoVGltZSwgV2F0dHMpKQpBdmdSZXNQbG90ICsgZ2VvbV9saW5lKCkgKyBnZW9tX3Ntb290aChtZXRob2QgPSBOVUxMLCBzZSA9IDk5KQoKIyBpbml0aWFsIHBsb3Qgc2hvd2luZyBhdmVyYWdlIEVWIGNoYXJnaW5nIHdpdGhvdXQgZ2VvbV9saW5lKCkgLSBub3QgdXNlZnVsIGhlcmUKQXZnRXZQbG90IDwtIGdncGxvdChBdmdFdlVzZSwgYWVzKFRpbWUsIFdhdHRzKSkKQXZnRXZQbG90ICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gTlVMTCwgc2UgPSA5OSwgY29sb3IgPSAicmVkIikKYGBgCgoKCmBgYHtyIGZpbmFsIG91dHB1dCBmb3IgdmlzdWFsaXphdGlvbn0KCkF2Z1Jlc1Bsb3QgKyBnZW9tX2xpbmUoKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9IE5VTEwsIHNlID0gOTksIGFlcyhjb2xvciA9ICJSZXNpZGVudGlhbCIpKSArCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IEF2Z0V2VXNlLCBtZXRob2QgPSBOVUxMLCBzZSA9IDk5LCBhZXMoY29sb3IgPSAiRWxlY3RyaWMgVmVoaWNsZSIpKSArCiAgZ2d0aXRsZSgiQXZlcmFnZSBFbGVjdHJpY2l0eSBEZW1hbmQgaW4gV2F0dHMiKSArIHhsYWIoIlRpbWUiKSArIAogIHlsYWIoIldhdHQgSG91cnMiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiTWVhc3VyZWQgRXZlcnkgMTAgTWludXRlcyAoOTklIENJKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbChuYW1lPSJsZWdlbmQiLCB2YWx1ZXM9YygicmVkIiwgImJsdWUiKSkKYGBgCgpgYGB7ciBpbi1kZXB0aCBzaWRlIGJ5IHNpZGUgdmlldyBvZiBkYXRhfQoKdHNfcGxvdChXYXR0VFMsCiAgICAgICAgdGl0bGUgPSAiUmVzaWRlbnRpYWwgRWxlY3RyaWNpdHkgRGVtYW5kIHZzIFJlc2lkZW50aWFsIEVWIEVsZWN0cmljaXR5IFVzZSIsCiAgICAgICAgWXRpdGxlID0gIldhdHRzIiwKICAgICAgICBYdGl0bGUgPSAiVGltZSAoMjAxMCkiLCAKICAgICAgICBzbGlkZXIgPSBUUlVFKQpgYGAKCgpgYGB7ciBydW5uaW5nIGNvcnJlbGF0aW9uIGJldHdlZW4gcmVzaWRlbnRpYWwgZWxlY3RyaWNpdHkgZGVtYW5kIHZzIEVWIGNoYXJnaW5nIHVzYWdlfQoKV2F0dFRTbmV3IDwtIGFzX3RzaWJibGUoQ29tYmluZWRXYXR0cywgaW5kZXggPSBUaW1lKQoKcGxvdChydW5uaW5nKFdhdHRUU25ldyRSZXNXYXR0cywgV2F0dFRTbmV3JEV2V2F0dHMsIGZ1biA9IGNvciwgd2lkdGg9MzUwMCksIHBjaCA9ICcuJywgbWFpbj0iUnVubmluZyBDb3JyZWxhdGlvbiBvZiBFViBDaGFyZ2luZyB2cyBSZXNpZGVudGlhbCBFbGVjdHJpY2l0eSBEZW1hbmQiLAp4bGFiPSJSdW5uaW5nIE9ic2VydmF0aW9ucyIsCnlsYWI9IkNvcnJlbGF0aW9uIiwKc3ViPSIxIG1vbnRoIOKJiCA0LDMzMyBPYnNlcnZhdGlvbnMiKQoKYGBgCgpgYGB7ciBhbmFseXNpcyBvZiBkYWlseSBhdmVyYWdlcyBvcHBvc2VkIHRvIGV2ZXJ5IDEwIG1pbnV0ZXMgdGhyb3VnaCB0aGUgdGltZSBzZXJpZXN9CgpEYWlseVdhdHRQbG90IDwtIGdncGxvdChXYXR0X2xtLCBhZXMoRGF5LCBSZXNXYXR0cykpCkRhaWx5V2F0dFBsb3QgKyBnZW9tX2xpbmUoKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9IE5VTEwsIHNlID0gOTksIGFlcyhjb2xvciA9ICJSZXNpZGVudGlhbCIpKSArCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IFdhdHRfbG0sIG1ldGhvZCA9IE5VTEwsIHNlID0gOTksIGFlcyh4ID0gRGF5LCB5ID0gRXZXYXR0cywgY29sb3IgPSAiRWxlY3RyaWMgVmVoaWNsZSIpKSArCiAgZ2d0aXRsZSgiQXZlcmFnZSBFbGVjdHJpY2l0eSBEZW1hbmQgaW4gV2F0dHMiKSArIHhsYWIoIlRpbWUiKSArIAogIHlsYWIoIldhdHQgSG91cnMiKSArIAogIGxhYnMoc3VidGl0bGUgPSAiRGFpbHkgQXZlcmFnZSAoOTklIENJKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbChuYW1lPSJsZWdlbmQiLCB2YWx1ZXM9YygicmVkIiwgImJsdWUiKSkKCiMjIHRoaXMgY29kZSBpcyBhZGRlZCBzbyB0d28gZ3JhcGhzIGNhbiBiZSBjb21wYXJlZCBzaWRlLWJ5LXNpZGUKQXZnUmVzUGxvdCArIGdlb21fbGluZSgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gTlVMTCwgc2UgPSA5OSwgYWVzKGNvbG9yID0gIlJlc2lkZW50aWFsIikpICsKICBnZW9tX3Ntb290aChkYXRhID0gQXZnRXZVc2UsIG1ldGhvZCA9IE5VTEwsIHNlID0gOTksIGFlcyhjb2xvciA9ICJFbGVjdHJpYyBWZWhpY2xlIikpICsKICBnZ3RpdGxlKCJBdmVyYWdlIEVsZWN0cmljaXR5IERlbWFuZCBpbiBXYXR0cyIpICsgeGxhYigiVGltZSIpICsgCiAgeWxhYigiV2F0dCBIb3VycyIpICsgCiAgbGFicyhzdWJ0aXRsZSA9ICJNZWFzdXJlZCBFdmVyeSAxMCBNaW51dGVzICg5OSUgQ0kpIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKG5hbWU9ImxlZ2VuZCIsIHZhbHVlcz1jKCJyZWQiLCAiYmx1ZSIpKQpgYGAKCgpgYGB7ciBjbG9zZXIgbG9vayBhdCBrZXkgZGlmZmVyZW5jZXMgLSBjb3JyZWxhdGlvbn0KCiMjIGRhaWx5IGF2ZXJhZ2UKcGxvdChXYXR0X2xtJFJlc1dhdHRzLCBXYXR0X2xtJEV2V2F0dHMsIG1haW4gPSAiQ29ycmVsYXRpb24gb2YgRGFpbHkgQXZlcmFnZSBFbGVjdHJpY2l0eSAoV2F0dCkgVXNhZ2UiLAogICAgIHhsYWIgPSAiUmVzaWRlbnRpYWwgRWxlY3RyaWNpdHkgVXNhZ2UiLCB5bGFiID0gIkVWIENoYXJnaW5nIFVzYWdlIiwKICAgICBwY2ggPSAxLCBmcmFtZSA9IEZBTFNFKQphYmxpbmUobG0oV2F0dF9sbSRFdldhdHRzIH4gV2F0dF9sbSRSZXNXYXR0cywgZGF0YSA9IFdhdHRfbG0pLCBjb2wgPSAiYmx1ZSIpCgojIyBtZWFzdXJlZCBldmVyeSAxMCBtaW51dGVzCnBsb3QoQ29tYmluZWRXYXR0cyRSZXNXYXR0cywgQ29tYmluZWRXYXR0cyRFdldhdHRzLCBtYWluID0gIkNvcnJlbGF0aW9uIG9mIEF2ZXJhZ2UgRWxlY3RyaWNpdHkgKFdhdHQpIFVzYWdlLCBNZWFzdXJlZCBFdmVyeSAxMCBNaW51dGVzIiwKICAgICB4bGFiID0gIlJlc2lkZW50aWFsIEVsZWN0cmljaXR5IFVzYWdlIiwgeWxhYiA9ICJFViBDaGFyZ2luZyBVc2FnZSIsCiAgICAgcGNoID0gMSwgZnJhbWUgPSBGQUxTRSkKYWJsaW5lKGxtKENvbWJpbmVkV2F0dHMkRXZXYXR0cyB+IENvbWJpbmVkV2F0dHMkUmVzV2F0dHMsIGRhdGEgPSBDb21iaW5lZFdhdHRzKSwgY29sID0gImJsdWUiKQpgYGAKCmBgYHtyIHN1cHBvcnRpbmcgc3RhdGlzdGljYWwgb3V0cHV0cyBmb3IgZGFpbHkgYXZlcmFnZSBkYXRhIC0gaWRlbnRpZnlpbmcgcmVsZXZhbmNlL3VzZWZ1bG5lc3Mgb2YgdGVtcGVyYXR1cmUgZGF0YX0KCiMjIHNjYXR0ZXJwbG90IG1hdHJpeApwYWlycyh+IFJlc1dhdHRzICsgRXZXYXR0cyArIFRlbXAsIGRhdGEgPSBXYXR0X2xtKQoKIyNTaG93cyBhbGwgcGFpcmVkIHAtdmFsdWVzCmNvcl9wIDwtIGNvcl9wbWF0KFdhdHRfbG1bLCAtMV0pCmNvcl9wCgojI1Nob3dzIGFsbCBjb3JyZWxhdGlvbnMKY29yX3Rlc3QgPC0gY29yX21hdChXYXR0X2xtWywgLTFdKQpjb3JfdGVzdAoKYGBgCgpgYGB7ciBtb2RlbCBidWlsZGluZyAtIGRhaWx5IHZzIDEwIG1pbnV0ZSBpbnRlcnZhbHMsIHVzaW5nIHRlbXAgdnMuIHJlc2lkZW50aWFsIHZlcnN1cyBFVn0KCiMjIERhaWx5IGF2ZXJhZ2UgZnVsbCBtb2RlbCB3aXRoIFJlc1VzZSByZXNwb25zZSB2YXJpYWJsZQpNb2RlbDEgPC0gbG0oUmVzV2F0dHMgfiBFdldhdHRzICsgVGVtcCwgZGF0YSA9IFdhdHRfbG0pCnN1bW1hcnkoTW9kZWwxKQoKIyMgRGFpbHkgYXZlcmFnZSBmdWxsIG1vZGVsIHdpdGggRXZVc2UgcmVzcG9uc2UgdmFyaWFibGUKTW9kZWwyIDwtIGxtKEV2V2F0dHMgfiBSZXNXYXR0cyArIFRlbXAsIGRhdGEgPSBXYXR0X2xtKQpzdW1tYXJ5KE1vZGVsMikKCiMjIERhaWx5IGF2ZXJhZ2VzIGFuZCBUZW1wZXJhdHVyZQpNb2RlbDMgPC0gbG0oUmVzV2F0dHMgfiBUZW1wLCBkYXRhID0gV2F0dF9sbSkKc3VtbWFyeShNb2RlbDMpCgpNb2RlbDQgPC0gbG0oUmVzV2F0dHMgfiBFdldhdHRzLCBkYXRhID0gV2F0dF9sbSkKc3VtbWFyeShNb2RlbDQpCgpNb2RlbDUgPC0gbG0oRXZXYXR0cyB+IFRlbXAsIGRhdGEgPSBXYXR0X2xtKQpzdW1tYXJ5KE1vZGVsNSkKCiMjIEV2ZXJ5IDEwIG1pbnV0ZXMgd2l0aCBSZXNpZGVudGlhbCBVc2UgYXMgcmVzcG9uc2UgdmFyaWFibGUuIFNob3dzIG11Y2ggc3Ryb25nZXIgY29ycmVsYXRpb24KTW9kZWw2IDwtIGxtKFJlc1dhdHRzIH4gRXZXYXR0cywgZGF0YSA9IENvbWJpbmVkV2F0dHMpCnN1bW1hcnkoTW9kZWw2KQoKYGBgCg==